package com.ruicar.afs.cloud.basic.creditchange.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.basic.common.entity.*;
import com.ruicar.afs.cloud.basic.common.service.*;
import com.ruicar.afs.cloud.basic.creditchange.condition.RepaymentPlanChangeCondition;
import com.ruicar.afs.cloud.batch.frame.control.BatchHelper;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.contract.enums.*;
import com.ruicar.afs.cloud.common.util.EmptyUtils;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author chuke
 * @create 2020/7/4 13:54
 * 还款日变更
 */
@Slf4j
@RestController
@RequestMapping("/repaymentDateChange")
@AllArgsConstructor
public class RepaymentController {
    private final BasicFinancialAgreementService basicFinancialAgreementService;
    private final BasicRepaymentPlanService planService;
    private final BasicProductParamService paramService;
    private final BasicMainInfoService basicMainInfoService;
    private final BasicDebitInfoService basicDebitInfoService;
    private final BasicExpenseRecordDetailService basicExpenseRecordDetailService;
    private final BasicContractCustRelationService basicContractCustRelationService;
    private final BasicCustContactDetailsService basicCustContactDetailsService;

    @ApiOperation(value = "查询还款日变更详情页，业务办理区域数据")
    @PostMapping("/queryBusinessHandle")
    public IResponse<RepaymentPlanChangeCondition> queryBusinessHandle(@RequestParam("contractNo") String contractNo) {
        RepaymentPlanChangeCondition condition = new RepaymentPlanChangeCondition();
        BasicFinancialAgreement basicFinancialAgreement = basicFinancialAgreementService.getOne(Wrappers.<BasicFinancialAgreement>lambdaQuery().eq(BasicFinancialAgreement::getContractNo, contractNo).eq(BasicFinancialAgreement::getCostType, AssetTypeEnum.CAR_AMT));
        if (EmptyUtils.isEmpty(basicFinancialAgreement) || EmptyUtils.isEmpty(basicFinancialAgreement.getSettleRate())) {
            return new IResponse().fail("此合同的结算利率为空值！");
        }

        List<BasicRepaymentPlan> plans = planService.list(Wrappers.<BasicRepaymentPlan>lambdaQuery()
                .eq(BasicRepaymentPlan::getContractNo, contractNo)
                .eq(BasicRepaymentPlan::getStatus, RepaymentStatusEnum.UNPAID)
                .eq(BasicRepaymentPlan::getActualRent, 0)
                .orderByAsc(BasicRepaymentPlan::getTermNo));
        if (EmptyUtils.isEmpty(plans)) {
            return new IResponse().fail("没有查询到此合同的还款计划！");
        }
        BasicProductParam repayChangeLimitFrequency = paramService.getOne(Wrappers.<BasicProductParam>lambdaQuery().eq(BasicProductParam::getContractNo, contractNo).eq(BasicProductParam::getAtomKey, AfsEnumUtil.key(ProductAtomEnum.REPAY_CHANGE_LIMIT_FREQUENCY)));
        if (EmptyUtils.isEmpty(repayChangeLimitFrequency)) {
            return new IResponse().fail("未查询到产品配置的还款日变更次数！");
        }
        BasicProductParam repayChangeLimitCost = paramService.getOne(Wrappers.<BasicProductParam>lambdaQuery().eq(BasicProductParam::getContractNo, contractNo).eq(BasicProductParam::getAtomKey, AfsEnumUtil.key(ProductAtomEnum.REPAY_CHANGE_LIMIT_COST)));
        if (EmptyUtils.isEmpty(repayChangeLimitCost)) {
            return new IResponse().fail("未查询到产品配置的手续费信息！");
        }
        condition.setRepayChangeLimitFrequency(Integer.valueOf(repayChangeLimitFrequency.getAtomValue()));
        condition.setPoundage(new BigDecimal(repayChangeLimitCost.getAtomValue()));
        BigDecimal b = BigDecimal.valueOf(0);

        BasicRepaymentPlan basicRepaymentPlan = plans.get(1);

        condition.setOldDueDate(basicRepaymentPlan.getDueDate());
        condition.setRemainPrinciple(basicRepaymentPlan.getRemainPrinciple().add(basicRepaymentPlan.getReceivablePrinciple()));
        condition.setRealInterestRate(basicFinancialAgreement.getCustRate());

        return new IResponse().setData(condition);
    }

    @ApiOperation(value = "还款日变更校验")
    @PostMapping("/repaymentChangeValid")
    public IResponse<String> valid(@RequestParam("contractNo") String contractNo) {
        BasicDebitInfo basicDebitInfo = basicDebitInfoService.getOne(Wrappers.<BasicDebitInfo>lambdaQuery()
                .eq(BasicDebitInfo::getContractNo, contractNo));
        //逾期客户不允许变更
        if (basicDebitInfo.getCurrentAbsoluteOverdue() > 0) {
            return new IResponse().setData("逾期客户不允许变更还款日");
        }
        List<BasicProductParam> productParams = paramService.list(Wrappers.<BasicProductParam>lambdaQuery().eq(BasicProductParam::getContractNo, contractNo));


        Boolean isRepayChange = false;
        Boolean repayChangeInitial = false;
        Boolean repayChangeDays = false;
        Boolean changeLimitCost = false;
        Boolean changeLimitFrequency = false;
        for (BasicProductParam param : productParams) {
            //产品是否允许还款日变更
            if (param.getAtomKey() == ProductAtomEnum.IS_REPAY_CHANGE) {
                isRepayChange = true;
                if (AfsEnumUtil.key(YesOrNoNumEnum.NO).equals(param.getAtomValue())) {
                    return new IResponse().setData("此合同的产品不允许做还款日变更");
                }
            }
            //还款日变更是否允许首期变更
            if (param.getAtomKey() == ProductAtomEnum.REPAY_CHANGE_INITIAL) {
                repayChangeInitial = true;
                if (AfsEnumUtil.key(YesOrNoNumEnum.NO).equals(param.getAtomValue())) {
                    return new IResponse().setData("该合同产品首期不允许做还款日变更");
                }
                List<BasicRepaymentPlan> repaymentPlans = planService.list(Wrappers.<BasicRepaymentPlan>lambdaQuery()
                        .eq(BasicRepaymentPlan::getContractNo, contractNo)
                        .eq(BasicRepaymentPlan::getStatus, RepaymentStatusEnum.REPAID)
                        .orderByAsc(BasicRepaymentPlan::getTermNo));
                if (EmptyUtils.isEmpty(repaymentPlans)) {
                    return new IResponse().setData("该合同产品首期不允许做还款日变更");
                }
            }
            //校验还款日变更手续费率是否配置
            if (param.getAtomKey() == ProductAtomEnum.REPAY_CHANGE_LIMIT_COST) {
                changeLimitCost = true;
            }
            if (param.getAtomKey() == ProductAtomEnum.REPAY_CHANGE_LIMIT_FREQUENCY) {
                changeLimitFrequency = true;
            }


            //申请日期在还款日期前1天申请（1是根据产品配置的参数获取）
            if (param.getAtomKey() == ProductAtomEnum.REPAY_CHANGE_DAYS) {
                repayChangeDays = true;
                List<BasicRepaymentPlan> repaymentPlans = planService.list(Wrappers.<BasicRepaymentPlan>lambdaQuery().eq(BasicRepaymentPlan::getContractNo, contractNo).eq(BasicRepaymentPlan::getStatus, RepaymentStatusEnum.UNPAID).orderByAsc(BasicRepaymentPlan::getTermNo));
                if (repaymentPlans.size() != 0) {
                    Date dueDate = repaymentPlans.get(0).getDueDate();

                    Calendar tempStart = Calendar.getInstance();
                    tempStart.setTime(DateUtil.date());
                    Calendar tempEnd = Calendar.getInstance();
                    tempEnd.setTime(dueDate);

                    tempEnd.add(Calendar.DATE, +1);//日期加1(包含结束)
                    int days = 0;
                    while (tempStart.before(tempEnd)) {
                        if (!BatchHelper.isHoliday(DateUtil.format(tempStart.getTime(), "yyyyMMdd"))) {
                            days++;
                        }
                        tempStart.add(Calendar.DAY_OF_YEAR, 1);
                    }
                    if (days < Integer.valueOf(param.getAtomValue())) {
                        return new IResponse().setData("申请日期必须在还款日期前" + param.getAtomValue() + "个工作日前申请");
                    }
                }
            }
        }
        if (!isRepayChange) {
            return new IResponse().setData("缺少贷后类参数：是否允许还款日变更");
        }
        if (!repayChangeInitial) {
            return new IResponse().setData("缺少贷后类参数：还款日变更是否允许首期变更");
        }
        if (!repayChangeDays) {
            return new IResponse().setData("缺少贷后类参数：还款日变更在还款日前多少天(天)");
        }
        if (!changeLimitCost) {
            return new IResponse().setData("未查询到产品配置的还款日变更手续费信息！");
        }
        if (!changeLimitFrequency) {
            return new IResponse().setData("未查询到产品配置的还款日变更次数！");
        }
        BasicFinancialAgreement basicFinancialAgreement = basicFinancialAgreementService.getOne(Wrappers.<BasicFinancialAgreement>lambdaQuery().eq(BasicFinancialAgreement::getContractNo, contractNo).eq(BasicFinancialAgreement::getCostType, AssetTypeEnum.CAR_AMT));
        if (EmptyUtils.isEmpty(basicFinancialAgreement) || EmptyUtils.isEmpty(basicFinancialAgreement.getSettleRate())) {
            return new IResponse().setData("此合同的结算利率为空值");
        }
        //校验还款计划是否已经是最后一期，最后一期未还的不允许做还款日变更
        List<BasicRepaymentPlan> plans = planService.list(Wrappers.<BasicRepaymentPlan>lambdaQuery()
                .eq(BasicRepaymentPlan::getContractNo, contractNo)
                .eq(BasicRepaymentPlan::getStatus, RepaymentStatusEnum.UNPAID)
                .eq(BasicRepaymentPlan::getActualRent, 0)
                .orderByAsc(BasicRepaymentPlan::getTermNo));
        if (EmptyUtils.isEmpty(plans)) {
            return new IResponse().setData("没有查询到此合同的还款计划！");
        } else {
            if (plans.size() - 1 <= 0) {
                return new IResponse().setData("此合同未还款期数不满足还款日变更条件！剩余未还期数已不足2期或存在溢缴款冲抵租金的情况");
            }
        }

        return new IResponse().setData(Boolean.TRUE.toString());
    }

    @ApiOperation(value = "手机号查询")
    @PostMapping("/queryPhone")
    public IResponse<BasicCustContactDetails> queryPhone(@RequestParam("contractNo") String contractNo) {
        BasicContractCustRelation basicContractCustRelation = basicContractCustRelationService.getOne(Wrappers.<BasicContractCustRelation>query().lambda()
                .eq(BasicContractCustRelation::getContractNo, contractNo)
                .eq(BasicContractCustRelation::getCustRole, PersonRoleTypeEnum.MAIN_PERSON)
        );

        BasicCustContactDetails basicCustContactDetails = basicCustContactDetailsService.getOne(Wrappers.<BasicCustContactDetails>query().lambda()
                .eq(BasicCustContactDetails::getCustNo, basicContractCustRelation.getCustNo())
                .eq(BasicCustContactDetails::getContactType, ContactTypeEnum.PHONE)
        );
        return new IResponse().setData(basicCustContactDetails);
    }


}
